#include "wrapping_integers.hh"

using namespace std;

Wrap32 Wrap32::wrap( uint64_t n, Wrap32 zero_point )
{
  // Your code here.
  return Wrap32 { Wrap32( n ) + zero_point.raw_value_ };
}

uint64_t Wrap32::unwrap( Wrap32 zero_point, uint64_t checkpoint ) const
// 转换为从0开始的绝对编号
{
  // Your code here.
  // checkpoint = 前32位+left
  // 与checkpoint最近的可能有两个数（分布在checkpoint一左一右） 其中一个必定是 前32位+offset
  // 如果offset < left  那么另一个必定比checkpoint大 等于前32位+zero_point+0x1 0000 0000
  // 那么就要看checkpoint 更接近前32位+zero_point 还是前32位+zero_point+0x1 0000 0000
  // 两边同减去前32位和zero_point 就是看 left-point 更接近0 还是0x 1 0000 0000
  uint64_t offset = ( raw_value_ + 0x1'0000'0000 - zero_point.raw_value_ ) % 0x1'0000'0000;
  uint32_t left = checkpoint % 0x1'0000'0000;
  uint64_t high32 = checkpoint - left;
  //  if( offset == left) {
  //    return high32+checkpoint;
  //  } else if ( offset < left){
  if ( offset < left ) {
    if ( left - offset <= 0x8000'0000 ) { // 更接近前32位+zero_point
      return high32 + offset;
    } else {
      return high32 + offset + 0x1'0000'0000;
    }
  } else {
    // 同上，offset > left 那么另一个一定比check_point 小 等于前32位+zero_point-0x1 0000 0000
    if ( high32 == 0 || offset - left <= 0x8000'0000 ) { // 更接近前32位+zero_point
      return high32 + offset;
    } else {
      return high32 + offset - 0x1'0000'0000;
    }
  }
}
